package com.fruits.login.handler;

import com.fruits.login.annotation.EnCrypt;
import com.fruits.login.dto.CryptDto;
import com.sghd.common.utils.codec.CryptUtils;
import com.sghd.common.utils.json.JsonUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;

import java.io.IOException;
import java.util.List;

/**
 * @author Allen
 * @date 2019/01/29
 */
public class CryptMethodReturnHandler extends RequestResponseBodyMethodProcessor {
    public CryptMethodReturnHandler(List<HttpMessageConverter<?>> converters) {
        super(converters);
    }

    /**
     * 该处理程序是否支持给定的方法返回类型(只有返回true才回去调用handleReturnValue)
     */
    @Override
    public boolean supportsReturnType(MethodParameter methodParameter) {
        return super.supportsReturnType(methodParameter) || methodParameter.hasMethodAnnotation(EnCrypt.class);
    }

    /**
     * 处理给定的返回值
     * 通过向 ModelAndViewContainer 添加属性和设置视图或者
     * 通过调用 ModelAndViewContainer.setRequestHandled(true) 来标识响应已经被直接处理(不再调用视图解析器)
     */
    @Override
    public void handleReturnValue(Object o, MethodParameter methodParameter,
                                  ModelAndViewContainer modelAndViewContainer,
                                  NativeWebRequest nativeWebRequest)
            throws IOException, HttpMediaTypeNotAcceptableException {

        CryptDto cryptDto = new CryptDto();
        String jsonStr = JsonUtils.object2String(o);
//        System.out.println("handleReturnValue---------------" + jsonStr);
        if (methodParameter.hasMethodAnnotation(EnCrypt.class)) {
            EnCrypt enCrypt = methodParameter.getMethodAnnotation(EnCrypt.class);
            if (enCrypt.ignore()) {
                super.handleReturnValue(o, methodParameter, modelAndViewContainer, nativeWebRequest);
                return;
            }
        }
        cryptDto.setBody(CryptUtils.encryptDESIV(jsonStr,"urBS2Qa@"));
        super.handleReturnValue(cryptDto, methodParameter, modelAndViewContainer, nativeWebRequest);
    }
}
